﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections;


namespace KanaInput
{
    /// <summary>
    /// Input.xaml 的交互逻辑
    /// </summary>
    public partial class Input : Window
    {
        public enum TYPE
        {
            HIRAGANA,
            KATAKANA,
            AO_GANA,
            AO_KANA,
            ALL
        }
        public TYPE type;
        private string text;
        private ArrayList target_gork;
        private ArrayList target_romaji;
        private ArrayList type_index;
        private int input_index;
        private int input_count;
        private string input_text;

        private string hiragana;
        private string katakana;
        private string[] romaji;

        private string[] ao_gana;
        private string[] ao_kana;
        private string[] ao_romaji;

        private FlowDocument flow;

        public Input()
        {
            InitializeComponent();
            
            this.hiragana = "あいうえお" +
                            "かきくけこ" +
                            "さしすせそ" +
                            "たちつてと" +
                            "なにぬねの" +
                            "はひふへほ" +
                            "まみむめも" +
                            "やゆよ" +
                            "らりるれろ" +
                            "ん";
            this.katakana = "アイウエオ" +
                            "カキクケコ" +
                            "サシスセソ" +
                            "タチツテト" +
                            "ナニヌネノ" +
                            "ハヒフヘホ" +
                            "マミムメモ" +
                            "ヤユヨ" +
                            "ラリルレロ" +
                            "ン";
            this.romaji = ("a i u e o " +
                          "ka ki ku ke ko " +
                          "sa shi su se so " +
                          "ta chi tsu te to " +
                          "na ni nu ne no " +
                          "ha hi fu he ho " +
                          "ma mi mu me mo " +
                          "ya yu yo " +
                          "ra ri ru re ro " +
                          "nn").Split(' ');

            this.ao_kana = ("キャ キュ キョ " +
                            "シャ シュ ショ " +
                            "チャ チュ チョ " +
                            "ニャ ニュ ニョ " +
                            "ヒャ ヒュ ヒョ " +
                            "ミャ ミュ ミョ " +
                            "リャ リュ リョ " +
                            "ギャ ギュ ギョ " +
                            "ジャ ジュ ジョ " +
                            "ビャ ビュ ビョ " +
                            "ピャ ピュ ピョ").Split(' ');
            this.ao_gana = ("きゃ きゅ きょ " +
                            "しゃ しゅ しょ " +
                            "ちゃ ちゅ ちょ " +
                            "にゃ にゅ にょ " +
                            "ひゃ ひゅ ひょ " +
                            "みゃ みゅ みょ " +
                            "りゃ りゅ りょ " +
                            "ぎゃ ぎゅ ぎょ " +
                            "じゃ じゅ じょ " +
                            "びゃ びゅ びょ " +
                            "ぴゃ ぴゅ ぴょ").Split(' ');
            this.ao_romaji = ("kya kyu kyo " +
                              "sya syu syo " +
                              "cya cyu cyo " +
                              "nya nyu nyo " +
                              "hya hyu hyo " +
                              "mya myu myo " +
                              "rya ryu ryo " +
                              "gya gyu gyo " +
                              "jya jyu jyo " +
                              "bya byu byo " +
                              "pya pyu pyo").Split(' ');
            this.flow = new FlowDocument();

            this.text = "";
            this.input_index = 0;
            this.input_count = 0;
            this.target_gork = new ArrayList();
            this.target_romaji = new ArrayList();
            this.type_index = new ArrayList();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 根据录入类型设置窗口名
            switch (this.type)
            {
                case TYPE.HIRAGANA:
                    this.Title += "平假名";
                    break;
                case TYPE.KATAKANA:
                    this.Title += "片假名";
                    break;
                case TYPE.AO_GANA:
                    this.Title += "拗音(平)";
                    break;
                case TYPE.AO_KANA:
                    this.Title += "拗音(片)";
                    break;
                case TYPE.ALL:
                    this.Title += "混合";
                    break;
                default:
                    this.Title += "未知";
                    break;
            }

            // 目标文本框与输入文本框均为窗口的宽度
            this.TargetTextBox.Width = this.InputTextBox.Width = this.Width;

            // 默认输入文本框获取焦点
            this.InputTextBox.Focus();

            // 禁止目标文本框获取到焦点且设置为只读
            this.TargetTextBox.Focusable = false;
            this.TargetTextBox.IsReadOnly = true;

            // 禁止计时器获取到焦点且设置为只读
            /*this.TimerTextBox.Focusable = false;
            this.TimerTextBox.IsReadOnly = true;*/

            // 生成目标文本框内容
            this.setTargetContent();

            // 设置已输入文本为空
            this.input_text = "";
        }

        private void setTargetContent()
        {
            this.text = "";
            this.flow.Blocks.Clear();

            Random r = new Random();
            int line_length;
            if (this.type == TYPE.HIRAGANA || this.type == TYPE.KATAKANA)
            {
                // line_length = "あああああああああああああああああああああああああああああああ".Length;
                // line_length = 31;
                line_length = 24;
            }
            else if (this.type == TYPE.AO_GANA || this.type == TYPE.AO_KANA || this.type == TYPE.ALL)
            {
                line_length = 13;
            }
            else
            {
                line_length = 13;
            }
            int rand;
            // 一共10行
            for (int i = 0; i < 10; ++i)
            {
                for (int j = 0; j < line_length; ++j)
                {
                    switch (this.type)
                    {
                        case TYPE.HIRAGANA:
                            rand = r.Next(0, this.hiragana.Length);
                            this.text += this.hiragana[rand];
                            this.target_gork.Add(this.hiragana[rand]);
                            this.target_romaji.Add(this.romaji[rand]);
                            this.type_index.Add(TYPE.HIRAGANA);
                            break;
                        case TYPE.KATAKANA:
                            rand = r.Next(0, this.katakana.Length);
                            this.text += this.katakana[rand];
                            this.target_gork.Add(this.katakana[rand]);
                            this.target_romaji.Add(this.romaji[rand]);
                            this.type_index.Add(TYPE.KATAKANA);
                            break;
                        case TYPE.AO_GANA:
                            rand = r.Next(0, this.ao_gana.Length);
                            this.text += this.ao_gana[rand];
                            this.target_gork.Add(this.ao_gana[rand]);
                            this.target_romaji.Add(this.ao_romaji[rand]);
                            this.type_index.Add(TYPE.AO_GANA);
                            break;
                        case TYPE.AO_KANA:
                            rand = r.Next(0, this.ao_kana.Length);
                            this.text += this.ao_kana[rand];
                            this.target_gork.Add(this.ao_kana[rand]);
                            this.target_romaji.Add(this.ao_romaji[rand]);
                            this.type_index.Add(TYPE.AO_KANA);
                            break;
                        case TYPE.ALL:
                            rand = r.Next(0, 4);
                            switch (rand)
                            {
                                case 0:
                                    rand = r.Next(0, this.hiragana.Length);
                                    this.text += this.hiragana[rand];
                                    this.target_gork.Add(this.hiragana[rand]);
                                    this.target_romaji.Add(this.romaji[rand]);
                                    this.type_index.Add(TYPE.HIRAGANA);
                                    break;
                                case 1:
                                    rand = r.Next(0, this.katakana.Length);
                                    this.text += this.katakana[rand];
                                    this.target_gork.Add(this.katakana[rand]);
                                    this.target_romaji.Add(this.romaji[rand]);
                                    this.type_index.Add(TYPE.KATAKANA);
                                    break;
                                case 2:
                                    rand = r.Next(0, this.ao_gana.Length);
                                    this.text += this.ao_gana[rand];
                                    this.target_gork.Add(this.ao_gana[rand]);
                                    this.target_romaji.Add(this.ao_romaji[rand]);
                                    this.type_index.Add(TYPE.AO_GANA);
                                    break;
                                case 3:
                                    rand = r.Next(0, this.ao_kana.Length);
                                    this.text += this.ao_kana[rand];
                                    this.target_gork.Add(this.ao_kana[rand]);
                                    this.target_romaji.Add(this.ao_romaji[rand]);
                                    this.type_index.Add(TYPE.AO_KANA);
                                    break;
                                default:
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
            Paragraph p = new Paragraph();
            this.text = this.text.TrimEnd();
            Run run = new Run(this.text);
            p.Inlines.Add(run);
            p.Foreground = new SolidColorBrush(Color.FromRgb(200, 200, 200));
            this.flow.Blocks.Add(p);
            this.TargetTextBox.Document = this.flow;
        }

        private void ReturnButton_Click(object sender, RoutedEventArgs e)
        {
            MainWindow mainWindow = new MainWindow();
            mainWindow.Show();
            this.Close();
        }

        private void setWordsForeground()
        {
            this.flow.Blocks.Clear();
            Paragraph p1 = new Paragraph();
            Run run1 = new Run(this.text.Substring(0, this.input_text.Length));
            Run run2 = new Run(this.text.Substring(this.input_text.Length));
            run1.Foreground = new SolidColorBrush(Color.FromRgb(0, 0, 0));
            run2.Foreground = new SolidColorBrush(Color.FromRgb(200, 200, 200));
            p1.Inlines.Add(run1);
            p1.Inlines.Add(run2);
            this.flow.Blocks.Add(p1);
            this.TargetTextBox.Document = this.flow;
        }

        private void MenuItemReset_Click(object sender, RoutedEventArgs e)
        {
            this.target_gork.Clear();
            this.target_romaji.Clear();
            this.input_count = 0;
            this.input_index = 0;
            this.TargetTextBox.Document = new FlowDocument();
            this.setTargetContent();
            this.InputTextBox.Text = "";
            // this.TimerTextBox.Text = "00:00:00";
        }

        private void InputTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            string input_string = this.InputTextBox.Text;
            if (input_string.Equals(this.target_romaji[this.input_index]))
            {
                this.InputTextBox.Text = "";
                this.input_text += this.target_gork[this.input_index];
                ++this.input_count;
                ++this.input_index;
                this.setWordsForeground();
            }

            if (this.input_count >= this.target_gork.Count)
            {
                MessageBoxResult result = MessageBox.Show("录入练习已完成，是否要重置？", "系统提示", MessageBoxButton.OKCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.OK)
                {
                    this.target_gork.Clear();
                    this.target_romaji.Clear();
                    this.input_count = 0;
                    this.input_index = 0;
                    this.TargetTextBox.Document = new FlowDocument();
                    this.setTargetContent();
                    this.InputTextBox.Text = "";
                    // this.TimerTextBox.Text = "00:00:00";
                }
            }
        }
    }
}
